<?php

namespace App\Http\Controllers\Api;

use App\Exceptions\BusinessException;
use App\Models\AddressModel;
use App\Models\OrderGoodsModel;
use App\Models\OrderModel;
use App\Models\OrderRefundModel;
use App\Models\SupplyModel;
use App\Models\UserModel;
use App\Utils\ControllerModelTrait;
use App\Utils\Push\UPush;
use App\Utils\ResponseEnum;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class OrderController extends ApiController
{
    use ControllerModelTrait;

    /**
     * 获取订单列表
     * @param Request $request
     * @return JsonResponse
     */
    public function getList(Request $request): JsonResponse
    {
        $Model = OrderModel::getModel($request);
        if ($request->input('uid'))
            $Model = $this->getUserOrderModel($Model, $request);
        $sortField = $request->input('status') == 9 ? 'updated_at' : 'id';
        $paginate = $this->getPagedData($Model, $request, $sortField);
        $data = $this->getOrderData($paginate->items(), empty($request->input('web')));
        return $this->success($this->getPaginate($paginate, $data));
    }

    /**
     * 订单详情
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function getOrderInfo(Request $request): JsonResponse
    {
        $orderNo = $this->verifyString('order_no');
        $order = OrderModel::where('order_no', $orderNo)->first();
        $order->goods_list = groupGoodsData(OrderGoodsModel::where('order_no', $orderNo)->get()->toArray(), false, '');
        $order->status = OrderModel::getOrderStatusCode($order);
        $order->status_text = OrderModel::getOrderStatusText($order);
        $order->address = $this->getOrderAddress($order);
        if ($order->refund_status == 1)
            $order = $this->getRefundOrderData($order);
        return $this->success($order);
    }

    /**
     * 核对订单用户序号
     * @param Request $request
     * @return JsonResponse
     */
    public function checkOrderUid(Request $request): JsonResponse
    {
        $orderCollection = OrderModel::where('pay_status', 1)->where('uid', 0)->where('app_type', '!=', '网店')->limit(3)->get();
        if ($orderCollection->isEmpty())
            return $this->fail([400010, '无数据']);
        $usernames = $orderCollection->pluck('username')->toArray();
        $uidData = UserModel::whereIn('username', $usernames)->pluck('id', 'username');
        foreach ($orderCollection as $order) {
            $orderUsername = $order->username;
            $uid = $uidData[$orderUsername] ?? 0;
            if ($uid) {
                $order->uid = $uid;
                $order->save();
            }
        }
        return $this->success();
    }

    /**
     * 保存订单
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function doSave(Request $request): JsonResponse
    {
        $uid = $this->verifyInteger('uid');
        $expressFee = $this->verifyNumeric('express_fee');
        $goodsList = json_decode($request->input('goods_list'), true);
        if ($request->input('goods_total', 0) <= 0 || empty($goodsList))
            return $this->fail(ResponseEnum::CLIENT_PARAMETER_ERROR);
        $orderNo = intval(Carbon::now()->getPreciseTimestamp(4)) . mt_rand(100, 999) ;
        $this->saveOrderGoods($orderNo, $goodsList);
        $order = OrderModel::createOrder($uid, $orderNo, $expressFee, $this->getOrderPostData($request));
        if ($request->input('flag'))
            AddressModel::createAddress($uid, $request);
        return $this->success($order);
    }

    /**
     * 更新订单信息
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function doUpdate(Request $request): JsonResponse
    {
        $orderNo = $this->verifyString('order_no');
        $order = OrderModel::where('order_no', $orderNo)->first();
        if ($request->input('pay_status'))
            $order->pay_status = $request->input('pay_status');
        $order->save();
        return $this->success();
    }

    /**
     * 取消订单
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function cancelOrder(Request $request): JsonResponse
    {
        $orderNo = $this->verifyString('order_no');
        $order = OrderModel::where('order_no', $orderNo)->where('pay_status', 0)->first();
        if ($order) {
            $order->uid = 0;
            $order->save();
        }
        return $this->success($order);
    }

    /**
     * 确认订单完结
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function finishOrder(Request $request): JsonResponse
    {
        $orderNo = $this->verifyString('order_no');
        $order = OrderModel::where('order_no', $orderNo)->where('refund_status', 0)->first();
        $order->finish_status = 1;
        $order->save();
        return $this->success($order);
    }

    /**
     * 获取用户订单数据
     * @param $orders
     * @param bool $doGoodsGroup
     * @return array
     */
    private function getOrderData($orders, bool $doGoodsGroup = true): array
    {
        $list = [];
        $orderNos = array_column(json_decode(json_encode($orders),true), 'order_no');
        $OrderGoodsCollection = OrderGoodsModel::whereIn('order_no', $orderNos)
            ->select(['order_no', 'goods_id', 'goods_name', 'thumbnail', 'goods_num', 'price', 'color', 'size', 'weight', 'sname', 'done_status', 'refund', 'doned_at'])->get();
        foreach ($orders as $order) {
            if ($doGoodsGroup)
                $order->goods_list = groupGoodsData($OrderGoodsCollection->where('order_no', $order->order_no)->toArray(), false, '');
            else
                $order->goods_list = array_values($OrderGoodsCollection->where('order_no', $order->order_no)->toArray());
            $order->status = OrderModel::getOrderStatusCode($order);
            $order->status_text = OrderModel::getOrderStatusText($order);
            #todo 获取退单状态
            $order->refund_service_status = 1;
            $order->refund_status_text = OrderRefundModel::getRefundStatusText($order->refund_service_status);
            $list[] = $order;
        }
        return $list;
    }

    /**
     * 匹配状态获取用户订单
     * status转换成二进制匹配如下状态
     * finish refund done express pay
     *   0      0     0     0      0
     * @param $Model
     * @param $request
     * @return mixed
     */
    private function getUserOrderModel($Model, $request): mixed
    {
        if ($request->has('status')) {
            $status = intval($request->input('status', -1));
            $Model = match ($status) {
                0  => $Model->where('pay_status', 0)->where('refund_status', 0), # 待付
                1  => $Model->where('pay_status', 1)->where('refund_status', 0)->where('done_status', 0), #待发
                3  => $Model->where('pay_status', 1)->where('refund_status', 0)->where('finish_status', 0)
                    ->where('done_status', 1)->where('express_status', 1),    # 待收
                9  => $Model->where('pay_status', 1)->where('refund_status', '>', 0), # 退款
                23 => $Model->where('pay_status', 1)->where('refund_status', 0)->where('finish_status', 1)
                    ->where('express_status', 1), # 完结
                default => $Model->where('pay_status', '>=', 0)
            };
        }
        return $Model;
    }

    /**
     * 批量添加订单商品
     * @param $orderNo
     * @param $goodsList
     * @return void
     */
    private function saveOrderGoods($orderNo, $goodsList): void
    {
        $sids = array_column($goodsList, 'sid');
        $supplyCollection = SupplyModel::whereIn('ID', array_flip(array_flip($sids)))
            ->select('ID', 'CName', 'building', 'floor', 'room')->get();
        foreach ($goodsList as $goods) {
            $supply = $supplyCollection->where('ID', $goods['sid'])->first();
            OrderGoodsModel::createOrderGoods($orderNo, $goods, $supply);
        }
    }

    /**
     * 获取订单提交的参数
     * @param $request
     * @return array
     */
    private function getOrderPostData($request): array
    {
        $postData = $request->only(['username', 'goods_total', 'express_company', 'gold', 'remark', 'daifa_fee',
            'check_fee', 'package_fee', 'brand_fee', 'wishcard_fee', 'brand_word', 'wishcard_word',
            'province', 'province_text', 'city', 'city_text', 'district', 'district_text',
            'addr', 'name', 'mobile']);
        $postData['app_type'] = $request->input('app_type') ? $request->input('app_type') : '网页';
        return array_filter($postData);
    }

    /**
     * 获取退款订单流程进度
     * @param $order
     * @return mixed
     */
    private function getRefundOrderData($order): mixed
    {
        $refundOrder = OrderRefundModel::where('order_no', $order->order_no)->orderByDesc('status')->first();
        if ($refundOrder) {
            $order->refund_service_status = $refundOrder->status ?: 1;
            $order->reason = $refundOrder->reason;
            $order->response = $refundOrder->response;
            $order->refund_status_text = OrderRefundModel::getRefundStatusText($refundOrder->status);
            $order->refund_express_no = $refundOrder->refund_express_no;
            $order->refund_express_company = $refundOrder->refund_express_company;
        }
        return $order;
    }

    /**
     * 获取订单地址信息
     * @param $order
     * @return array
     */
    private function getOrderAddress($order): array
    {
        return [
            'name'		    => $order->name,
            'mobile'	    => $order->mobile,
            'province'      => $order->province,
            'province_text'	=> $order->province_text,
            'city'          => $order->city,
            'city_text'     => $order->city_text,
            'district'      => $order->district,
            'district_text' => $order->district_text,
            'address'	    => $order->addr
        ];
    }

    public function test(): void
    {
        $Push = new UPush();
        $Push->send(1350, '测试', '退款通知',['order_no' => time()]);
    }
}
